﻿@page "/InstallApp"
@using Microsoft.JSInterop

<UploadProgress Msg="@_progressMsg" Overlay="overlay" Progress="_progress"></UploadProgress>

<MSheet>
    <MTabs BackgroundColor="indigo"
    Dark
    SliderColor="yellow" Grow>
        <MTab>在线安装</MTab>
        <MTab>上传程序包安装</MTab>
        <MTabItem>
            在线安装
        </MTabItem>
        <MTabItem>
            上传程序包安装
            @* <MButton OnClick="OpenFilePicker">选择文件</MButton> *@

            @* <MTextField @bind-Value="_path" Label="根目录路径"></MTextField> *@

            <MButton Color="primary" OnClick="()=>LoadDirectoryTree(directoryNodeViewModel.directoryNode)">重新加载目录</MButton>
            <MRow>
                <!-- 左侧内容 -->
                <MCol Cols="6">
                    <div style="background-color: lightblue; padding: 20px;">
                        <MTreeview @bind-Open="@initiallyOpen" @bind-active="@selectedDirList"
                        Light
                        TItem="DirectoryNode"
                        TKey="string"
                        Items="directoryNodeViewModel.directoryNode.Children"
                        Activatable
                        ItemKey="u => u.FullPath"
                        ItemChildren="u => u.IsDir?u.Children:null"
                        ItemText="u => u.Name"
                        LoadChildren="LoadDirectoryTree"
                        >
                            <PrependContent>
                                @if (context.Item.IsDir)
                                {
                                    <MIcon>
                                        @(context.Open ? "mdi-folder-open" : "mdi-folder")
                                    </MIcon>
                                }
                                else
                                {
                                    <MIcon>
                                        @("mdi-language-html5")
                                    </MIcon>
                                }
                            </PrependContent>
                            <LabelContent Context="item">
                                <div style="display: flex; align-items: center; justify-content: space-between;">
                                    <span>@item.Item.Name</span>
                                    @if (@item.Item.Name.EndsWith(".jar")){
                                        <MButton Color="primary" Small OnClick="() => RunApp(item.Item)">
                                            运行
                                        </MButton>
                                    }else if (@item.Item.IsDir)
                                    {
                                        <MButton Color="primary" Small OnClick="() => EditNginx(item.Item)">
                                            配置Nginx为前端项目
                                        </MButton>
                                    }
                                </div>
                            </LabelContent>
                        </MTreeview>
                    </div>
                </MCol>

                <!-- 右侧内容 -->
                <MCol Cols="6">
                    <div style="background-color: lightgreen; padding: 20px;">
                        <MButton OnClick="LoadFile" IconName="mdi-file-cloud-outline"></MButton>
                        上传文件至->
                        <MTextField @bind-Value="uploadDir" Label="服务器路径"></MTextField>
                    </div>

                    <div style="background-color: lightgreen; padding: 20px;">
                        <MButton OnClick="LoadDir" IconName="mdi-folder-open"></MButton>
                        上传文件夹至->
                        <MTextField @bind-Value="uploadDir" Label="服务器路径"></MTextField>
                    </div>
                </MCol>
            </MRow>
        </MTabItem>
    </MTabs>
</MSheet>

<PDrawer @bind-Value="@nginxContextVisible" Title="编辑" Persistent>
    <NginxConfigEditor Config="nginxServerConfig" OnSave="SaveNginxConfig" OnCancel="CancelNginxConfig" />
</PDrawer>


@code {
    // [Inject]
    // public JSRuntime jSRuntime { get; set; }

    private bool nginxContextVisible = false;
    private NginxServerConfig nginxServerConfig = new NginxServerConfig();
    [Inject]
    public ISshClientService sshClientService { get; set; }
    [Inject]
    public ILocalFileService localFileService { get; set; }
    [Inject]
    public IRemoteNginxService RemoteNginxService { get; set; }

    /// <summary>
    /// 上传进度
    /// </summary>
    private bool overlay = false;
    private double _progress = 0;
    private string _progressMsg =string.Empty;

    private string fileContent;
    // private async Task OpenFilePicker()
    // {
    //     触发文件选择对话框
    //     await jSRuntime.InvokeVoidAsync("eval", "document.getElementById('fileInput').click()");
    // }
    //// <summary>
    /// 选中的路径
    /// </summary>
    private List<string> _selectedDirList = new List<string>();
    private List<string> selectedDirList { get => _selectedDirList;set
        {
            if (value != _selectedDirList)
            {
                _selectedDirList = value;
                selectedDir = directoryNodeViewModel.FindDirectoryNode(value.FirstOrDefault());
            }
        }
    }
    /// <summary>
    /// 选择中的路径
    /// </summary>
    private DirectoryNode _selectedDir;
    private DirectoryNode selectedDir{
        get => _selectedDir;
        set{
            if(value!=_selectedDir){
                _selectedDir = value;
                if(value==null)
                {
                    return;
                }
                if(value.IsDir){
                    uploadDir = value.FullPath;
                }else{
                    uploadDir=Path.GetDirectoryName(value.FullPath);
                }
            }
        }
    }
    /// <summary>
    /// 上传路径
    /// </summary>
    private string uploadDir;

    List<string> initiallyOpen = new() { "public" };

    private string editPath = string.Empty;

    private DirectoryNodeViewModel directoryNodeViewModel = new DirectoryNodeViewModel() { directoryNode = new DirectoryNode() { Name = "/", IsDir = true,FullPath="/" } };

    static Dictionary<string, string> files = new()
    {
        {"html", "mdi-language-html5"},
        {"js", "mdi-nodejs"},
        {"json", "mdi-code-json"},
        {"md", "mdi-language-markdown"},
        {"pdf", "mdi-file-pdf"},
        {"png", "mdi-file-image"},
        {"txt", "mdi-file-document-outline"},
        {"xls", "mdi-file-excel"}
    };

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if(firstRender){
            // 尝试连接
            if (!sshClientService.IsConnected){
                if (!sshClientService.Connect(out string errMsg)){
                    throw new Exception(errMsg);
                }
            }
            //加载目录
            directoryNodeViewModel = new DirectoryNodeViewModel() { directoryNode = new DirectoryNode() { Name = "/", IsDir = true, FullPath = "/" } };
            LoadDirectoryTree(directoryNodeViewModel.directoryNode);
        }
    }

    private async Task LoadDirectoryTree(DirectoryNode directoryNode)
    {
        await sshClientService.LoadDirectoryTree(directoryNode);
    }


    private async Task LoadFile(){
        var fileData=await localFileService.OpenFile();
        if (fileData.Key.IsNullOrWhiteSpace()){
            return;
        }
        var remoteFilePath = LinuxPathUtils.Combine(uploadDir, fileData.Key);
        // sshClientService.UploadFile(fileData.Value,remoteFilePath );
        overlay = true;
        await sshClientService.UploadFileAsync(fileData.Value, remoteFilePath, progress =>
        {
            _progress = progress;
            StateHasChanged();
        });
        overlay = false;
    }

    private async Task LoadDir()
    {
        if (uploadDir.IsNullOrWhiteSpace())
        {
            return;
        }
        var fileList=await localFileService.OpenDir();
        // linux目标文件夹
        var remoteFilePath = LinuxPathUtils.Combine(uploadDir, fileList.Key.Split(Path.DirectorySeparatorChar).Last());
        overlay = true;
        foreach (var item in fileList.Value)
        {
            try
            {
                _progressMsg = "正在上传文件:" + item;
                var fileData = await localFileService.OpenFile(item);
                // 文件相对选择目录的路径
                var fileRelativePath = LinuxPathUtils.GetRelativePath(item, fileList.Key);
                //上传到服务器的路径
                var updaloadFilePath = LinuxPathUtils.Combine(remoteFilePath, fileRelativePath);
                await sshClientService.UploadFileAsync(fileData.Value, updaloadFilePath, progress =>
                {
                    _progress = progress;
                    StateHasChanged();
                });
            }
            catch (Exception ex)
            {
                throw;
            }
        }

        overlay = false;
    }

    [JSInvokable]
    public async Task HandleFileSelected(byte[] fileData, string fileName)
    {
        using var stream = new MemoryStream(fileData);
        using var reader = new StreamReader(stream);
        fileContent = await reader.ReadToEndAsync();
    }

    /// <summary>
    /// 运行程序
    /// </summary>
    private void RunApp(DirectoryNode directoryNode)
    {
        var rootPath=LinuxPathUtils.GetLinuxDirectoryName(directoryNode.FullPath);
        CdCommand cdCommand = new CdCommand() { Path = rootPath };
        sshClientService.ExecuteCommand(cdCommand);
        sshClientService.ExecuteCommand(new StartJavaProjectCommand() { JarPath = directoryNode.FullPath,RunInBackground=true });
    }

    private void EditNginx(DirectoryNode directoryNode)
    {
        var dirName = directoryNode.FullPath.Split(Path.AltDirectorySeparatorChar).Last();
        var confilePath = LinuxPathUtils.Combine(RemoteNginxService.NginxConfigBasePath, dirName + ".conf");
        editPath = confilePath;
        nginxServerConfig=RemoteNginxService.GetCurrentConfig(confilePath);
        if (nginxServerConfig.RootPath.IsNullOrWhiteSpace())
        {
            nginxServerConfig.RootPath = directoryNode.FullPath;
        };
        if (nginxServerConfig.ServerName.IsNullOrWhiteSpace())
        {
            nginxServerConfig.ServerName = sshClientService.SshClientConnectInfo.Host;
        }
        ;
        nginxContextVisible = true;
    }

    private async Task SaveNginxConfig(NginxServerConfig config)
    {
        await RemoteNginxService.UpdateConfig(config, editPath);
    }

    private void CancelNginxConfig()
    {
        nginxContextVisible = false;
    }
}
